"""
告警事件管理相关的请求/响应模型
"""
from datetime import datetime
from typing import Optional, List, Annotated, Union

from pydantic import BaseModel, Field, ConfigDict, BeforeValidator

from app.models.alarm_models import AlarmDetail, AlarmRuleResponse
from app.schemas.device_schemas import DeviceLocationInfo
from common.base_enums import AlarmStatus, AlarmCloseReason


# 定义空字符串转None的验证函数（独立函数，更清晰）
def empty_str_to_none(v):
	if isinstance(v, str) and v.strip() == "":
		return None
	return v


class AlarmListRequest(BaseModel):
	"""告警列表查询请求模型"""
	page: int = Field(1, ge=1, description="页码")
	size: int = Field(20, ge=1, le=100, description="每页大小")
	province_code: Optional[str] = Field(None, description="省级代码")
	city_code: Optional[str] = Field(None, description="市级代码")
	area_code: Optional[str] = Field(None, description="区县级代码")
	status: Annotated[
		Union[str, None],
		BeforeValidator(empty_str_to_none),
		Field(description="告警状态（可选值：OPEN、ACKED、CLOSED、RECOVERED，空字符串将被视为None）")
	] = None
	station_id: Optional[int] = Field(None, description="台区ID")
	keyword: Optional[str] = Field(None, description="关键字")
	alarm_type: Optional[str] = Field(None, description="告警类型")
	start_time: Optional[datetime] = Field(None, description="开始时间")
	end_time: Optional[datetime] = Field(None, description="结束时间")


class AlarmListItem(BaseModel):
	"""告警列表项模型"""
	id: int
	meter_code: str
	alarm_type: str
	rule_name: Optional[str] = Field(None, description="告警规则名称")
	status: AlarmStatus
	close_reason: Annotated[
		Optional[AlarmCloseReason], BeforeValidator(empty_str_to_none), Field(description="关闭原因")] = None
	full_name: Optional[str] = None
	raised_at: datetime

	model_config = ConfigDict(from_attributes=True)


class AlarmListResponse(BaseModel):
	"""告警列表响应模型"""
	total: int
	items: List[AlarmListItem]


class AlarmRecoverRequest(BaseModel):
	"""告警恢复请求（工单回调）"""
	close_reason: AlarmCloseReason
	token: str = Field(..., description="幂等 token，由工单模块生成")


# ==================== 告警类型统计接口 ====================
class AlarmTypeItem(BaseModel):
	"""告警类型项"""
	alarm_type: str = Field(..., description="告警类型编码")
	alarm_name: str = Field(..., description="告警类型名称")


class AlarmTypeListResponse(BaseModel):
	"""告警类型列表响应"""
	items: List[AlarmTypeItem] = Field(..., description="告警类型列表")


class RegionAlarmStatsRequest(BaseModel):
	"""区域告警统计请求参数"""
	region_code: Optional[str] = Field(None, description="区域代码")
	province_code: Optional[str] = Field(None, description="省级代码")
	city_code: Optional[str] = Field(None, description="市级代码")
	area_code: Optional[str] = Field(None, description="区县级代码")
	alarm_type: Optional[str] = Field(None, description="告警类型（可选）")
	force_refresh: Optional[bool] = Field(False, description="是否强制刷新缓存， True:强制")
	start_time: datetime = Field(..., description="开始时间")
	end_time: datetime = Field(..., description="结束时间")


class RegionAlarmStatsItem(BaseModel):
	"""区域告警统计项"""
	region_id: Optional[int] = Field(None, description="区域id")
	region_code: str = Field(..., description="区域代码")
	region_name: str = Field(..., description="区域名称")
	alarm_count: int = Field(..., description="告警数量")


class RegionAlarmStatsResponse(BaseModel):
	"""区域告警统计响应"""
	items: List[RegionAlarmStatsItem] = Field(..., description="区域告警统计列表")


class AlarmTypeStatsRequest(BaseModel):
	"""告警类型统计请求参数"""
	region_code: Optional[str] = Field(None, description="区域代码")
	station_id: Optional[int] = Field(None, description="台区ID")
	province_code: Optional[str] = Field(None, description="省级代码")
	city_code: Optional[str] = Field(None, description="市级代码")
	area_code: Optional[str] = Field(None, description="区县级代码")
	start_time: Optional[datetime] = Field(None, description="开始时间")
	end_time: Optional[datetime] = Field(None, description="结束时间")
	alarm_type: Optional[str] = Field(None, description="告警类型（可选）")
	limit: int = Field(10, ge=1, le=50, description="返回数量限制，默认10条")
	force_refresh: Optional[bool] = Field(False, description="是否强制刷新缓存")


class AlarmTypeStatsItem(BaseModel):
	"""告警类型统计项"""
	alarm_type: Optional[str] = Field(None, description="告警类型编码")
	alarm_name: Optional[str] = Field(None, description="告警类型名称")
	alarm_count: Optional[int] = Field(None, description="告警数量")


class AlarmTypeStatsResponse(BaseModel):
	"""告警类型统计响应"""
	items: List[AlarmTypeStatsItem] = Field(..., description="告警类型统计列表")


class AlarmBatchAckRequest(BaseModel):
	"""批量确认请求"""
	alarm_ids: List[int] = Field(
		...,
		min_length=1,
		max_length=100,
		description="待确认告警 ID 列表"
	)


class AlarmCloseRequest(BaseModel):
	"""告警关闭请求模型"""
	close_reason: AlarmCloseReason


class AlarmAckResponse(BaseModel):
	"""告警确认响应模型"""
	id: int
	status: AlarmStatus

	model_config = ConfigDict(from_attributes=True)


class AlarmRecoverResponse(BaseModel):
	"""告警恢复响应模型"""
	id: int
	status: AlarmStatus

	model_config = ConfigDict(from_attributes=True)


class AlarmCloseResponse(BaseModel):
	"""告警关闭响应模型"""
	id: int
	status: AlarmStatus

	model_config = ConfigDict(from_attributes=True)


class AlarmDetailResponse(AlarmDetail):
	"""告警详情响应模型"""
	pass


class AlarmRuleListResponse(BaseModel):
	"""告警规则列表响应模型"""
	items: List[AlarmRuleResponse]


class AlarmBatchAckItem(BaseModel):
	alarm_id: int
	status: AlarmStatus


class AlarmBatchAckResponse(BaseModel):
	"""批量确认响应"""
	success: List[AlarmBatchAckItem]
	failed: List[AlarmBatchAckItem]


# ==================== 异常设备告警记录 ====================
class AbnormalDeviceAlarmRequest(BaseModel):
	"""异常设备告警记录查询请求"""
	device_type: str = Field(..., description="设备类型：METER/RTU/BOX")
	station_id: Optional[int] = Field(None, description="台区ID")
	start_time: datetime = Field(None, description="开始时间")
	end_time: datetime = Field(None, description="结束时间")
	page: int = Field(1, ge=1, description="页码")
	size: int = Field(20, ge=1, le=100, description="每页大小")


class AbnormalDeviceAlarmItem(BaseModel):
	"""异常设备告警记录项"""
	device_id: int = Field(..., description="设备ID")
	serial_no: str = Field(..., description="设备编号")
	alarm_type: str = Field(..., description="告警类型")
	raised_at: datetime = Field(..., description="告警产生时间")
	work_order_code: Optional[str] = Field(None, description="工单编号")
	work_order_id: Optional[int] = Field(None, description="工单ID")
	# 地址信息
	location_info: Optional[List[DeviceLocationInfo]] = Field(default_factory=list, description="位置信息列表")


class AbnormalDeviceAlarmResponse(BaseModel):
	"""异常设备告警记录响应"""
	total: int = Field(..., description="告警总条数")
	abnormal_total: int = Field(..., description="异常设备总数")
	items: List[AbnormalDeviceAlarmItem] = Field(..., description="告警列表")
	page: int = Field(..., description="当前页码")
	size: int = Field(..., description="每页大小")
	pages: int = Field(..., description="总页数")
	has_next: bool = Field(..., description="是否有下一页")
	has_prev: bool = Field(..., description="是否有上一页")
